"""
通知服务层
处理通知的创建、查询、更新等业务逻辑
"""

from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import desc

from db_models import NotificationDB, UserDB
from models import NotificationCreate, Notification, UserRole


class NotificationService:
    """通知服务类"""
    
    @staticmethod
    def create_notification(db: Session, notification_data: NotificationCreate) -> NotificationDB:
        """
        创建新通知
        
        Args:
            db: 数据库会话
            notification_data: 通知创建数据
            
        Returns:
            NotificationDB: 创建的通知数据库对象
        """
        db_notification = NotificationDB(
            user_id=notification_data.user_id,
            title=notification_data.title,
            message=notification_data.message
        )
        
        db.add(db_notification)
        db.commit()
        db.refresh(db_notification)
        return db_notification
    
    @staticmethod
    def get_user_notifications(
        db: Session, 
        user_id: int, 
        limit: Optional[int] = None,
        unread_only: bool = False
    ) -> List[NotificationDB]:
        """
        获取用户的通知列表
        
        Args:
            db: 数据库会话
            user_id: 用户ID
            limit: 限制数量
            unread_only: 是否只获取未读通知
            
        Returns:
            List[NotificationDB]: 通知列表
        """
        query = db.query(NotificationDB).filter(NotificationDB.user_id == user_id)
        
        if unread_only:
            query = query.filter(NotificationDB.is_read == False)
        
        query = query.order_by(desc(NotificationDB.created_at))
        
        if limit:
            query = query.limit(limit)
            
        return query.all()
    
    @staticmethod
    def get_unread_count(db: Session, user_id: int) -> int:
        """
        获取用户未读通知数量
        
        Args:
            db: 数据库会话
            user_id: 用户ID
            
        Returns:
            int: 未读通知数量
        """
        return db.query(NotificationDB).filter(
            NotificationDB.user_id == user_id,
            NotificationDB.is_read == False
        ).count()
    
    @staticmethod
    def mark_as_read(db: Session, notification_id: int, user_id: int) -> bool:
        """
        标记通知为已读
        
        Args:
            db: 数据库会话
            notification_id: 通知ID
            user_id: 用户ID（确保只能标记自己的通知）
            
        Returns:
            bool: 是否成功标记
        """
        notification = db.query(NotificationDB).filter(
            NotificationDB.id == notification_id,
            NotificationDB.user_id == user_id
        ).first()
        
        if notification:
            notification.is_read = True
            db.commit()
            return True
        return False
    
    @staticmethod
    def mark_all_as_read(db: Session, user_id: int) -> int:
        """
        标记用户所有通知为已读
        
        Args:
            db: 数据库会话
            user_id: 用户ID
            
        Returns:
            int: 标记的通知数量
        """
        updated_count = db.query(NotificationDB).filter(
            NotificationDB.user_id == user_id,
            NotificationDB.is_read == False
        ).update({"is_read": True})
        
        db.commit()
        return updated_count
    
    @staticmethod
    def delete_notification(db: Session, notification_id: int, user_id: int) -> bool:
        """
        删除通知
        
        Args:
            db: 数据库会话
            notification_id: 通知ID
            user_id: 用户ID（确保只能删除自己的通知）
            
        Returns:
            bool: 是否成功删除
        """
        notification = db.query(NotificationDB).filter(
            NotificationDB.id == notification_id,
            NotificationDB.user_id == user_id
        ).first()
        
        if notification:
            db.delete(notification)
            db.commit()
            return True
        return False
    
    @staticmethod
    def convert_to_pydantic(db_notification: NotificationDB) -> Notification:
        """
        将数据库模型转换为Pydantic模型
        
        Args:
            db_notification: 数据库通知对象
            
        Returns:
            Notification: Pydantic通知对象
        """
        return Notification(
            id=db_notification.id,
            user_id=db_notification.user_id,
            title=db_notification.title,
            message=db_notification.message,
            is_read=db_notification.is_read,
            created_at=db_notification.created_at,
            updated_at=db_notification.updated_at
        )
    
    @staticmethod
    def create_task_assignment_notification(
        db: Session, 
        user_id: int, 
        task_title: str,
        assigned_by: str = "管理员"
    ) -> NotificationDB:
        """
        创建任务分配通知
        
        Args:
            db: 数据库会话
            user_id: 接收通知的用户ID
            task_title: 任务标题
            assigned_by: 分配人
            
        Returns:
            NotificationDB: 创建的通知
        """
        notification_data = NotificationCreate(
            user_id=user_id,
            title="新任务分配",
            message=f"{assigned_by}为您分配了新任务：{task_title}"
        )
        
        return NotificationService.create_notification(db, notification_data)
    
    @staticmethod
    def create_task_completion_notification(
        db: Session,
        task_title: str,
        completed_by_username: str,
        admin_user_ids: List[int]
    ) -> List[NotificationDB]:
        """
        创建任务完成通知（发送给所有管理员）
        
        Args:
            db: 数据库会话
            task_title: 任务标题
            completed_by_username: 完成任务的用户名
            admin_user_ids: 管理员用户ID列表
            
        Returns:
            List[NotificationDB]: 创建的通知列表
        """
        notifications = []
        
        for admin_id in admin_user_ids:
            notification_data = NotificationCreate(
                user_id=admin_id,
                title="任务已完成",
                message=f"用户 {completed_by_username} 已完成任务：{task_title}"
            )
            
            notification = NotificationService.create_notification(db, notification_data)
            notifications.append(notification)
        
        return notifications
    
    @staticmethod
    def get_admin_user_ids(db: Session) -> List[int]:
        """
        获取所有管理员用户ID
        
        Args:
            db: 数据库会话
            
        Returns:
            List[int]: 管理员用户ID列表
        """
        admin_users = db.query(UserDB).filter(UserDB.role == UserRole.ADMIN).all()
        return [user.id for user in admin_users]
    
    @staticmethod
    def create_task_deletion_notification(
        db: Session,
        user_id: int,
        task_title: str,
        deleted_by: str = "管理员"
    ) -> NotificationDB:
        """
        创建任务删除通知
        
        Args:
            db: 数据库会话
            user_id: 接收通知的用户ID（任务原主人）
            task_title: 被删除的任务标题
            deleted_by: 删除操作者
            
        Returns:
            NotificationDB: 创建的通知
        """
        notification_data = NotificationCreate(
            user_id=user_id,
            title="任务已删除",
            message=f"{deleted_by}删除了您的任务：{task_title}"
        )
        
        return NotificationService.create_notification(db, notification_data)